#include "VProjectAttributeDialog.h"
#include "ui_VProjectAttributeDialog.h"
#include "VPathEditDialog.h"
#include "VFunctions.h"
#include "VGlobal.h"

#include <QStringList>
#include <QDebug>
#include <QCheckBox>
#include <QComboBox>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>

VProjectAttributeDialog::VProjectAttributeDialog(QWidget *parent, QString path) :
    QDialog(parent),
    ui(new Ui::VProjectAttributeDialog)
{
    ui->setupUi(this);
    _project_json = VFunctions::get_file_jsonDocument(path).object();
    _project_path = path;

    // 读取 config 的 project
    ui->combobox_brand->clear();
    ui->combobox_model->clear();

    QStringList list = VFunctions::get_folder_list(VGlobal::config_dir + "/project");
    foreach(QString path, list)
    {
        ui->combobox_brand->addItem(QFileInfo(path).fileName());
        ui->combobox_brand->setItemData(ui->combobox_brand->count()-1,
                                        QVariant::fromValue(VFunctions::get_folder_list(path)));
    }

    if(ui->combobox_brand->count() > 0)
    {
        on_combobox_brand_currentIndexChanged(0);
    }


    load_setting(_project_json.value("attribute").toObject());
    init_connect();
    on_update_configure();
    ui->btn_apply->setEnabled(false);
}

void VProjectAttributeDialog::init_connect()
{
    QObject::connect(ui->combobox_data_mode, static_cast<void (QComboBox::*)(int)>
                     (&QComboBox::currentIndexChanged), this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->combobox_model, static_cast<void (QComboBox::*)(int)>
                     (&QComboBox::currentIndexChanged), this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_crystal, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_start1, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_start2, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_start3, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_length1, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_length2, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_length3, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_start1, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_start2, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_start3, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_length1, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_length2, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xdata_length3, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);

    QObject::connect(ui->lineedit_url, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_output_folder_path, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_output_file_name, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->radio_create_exe, &QRadioButton::clicked, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->radio_create_lib, &QRadioButton::clicked, this, &VProjectAttributeDialog::on_update_configure);


    QObject::connect(ui->checkbox_less_pedantic, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_werror, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_float_reent, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_fsigned_char, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_fdollars_in_identifiers, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_int_long_reent, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_stack_auto, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_nostdinc, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_xram_movc, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_nooverlay, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_nogcse, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_noinduction, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_nolabelopt, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_noloopreverse, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_no_peep, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_noinvariant, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->combobox_optimization_focus, static_cast<void (QComboBox::*)(int)>
                     (&QComboBox::currentIndexChanged), this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->combobox_standard_compliance,static_cast<void (QComboBox::*)(int)>
                     (&QComboBox::currentIndexChanged), this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->combobox_data_mode, static_cast<void (QComboBox::*)(int)>
                     (&QComboBox::currentIndexChanged), this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_output_debug_info, &QCheckBox::toggled,
                     this, &VProjectAttributeDialog::on_update_configure);

    QObject::connect(ui->lineedit_ccpp_define, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_ccpp_other_control, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_ccpp_contain_paths, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);

    QObject::connect(ui->lineedit_asm_define, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_asm_contain_paths, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_asm_other_control, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkBox_a, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkBox_g, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkBox_j, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkBox_p, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);

    QObject::connect(ui->checkBox_use_target_plan, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->checkbox_nostdlib, &QCheckBox::toggled, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xram_start, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xram_length, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_iram_length, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_xstack_start, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_stack_start, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_data_start, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_data_length, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_start, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_length, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_code_name, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_const_name, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);

    QObject::connect(ui->lineedit_disable_warning_numbers, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_linker_contain_lib_files, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_linker_contain_paths, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
    QObject::connect(ui->lineedit_linker_other_control, &QLineEdit::textChanged, this, &VProjectAttributeDialog::on_update_configure);
}

void VProjectAttributeDialog::load_setting(QJsonObject object)
{
    QJsonObject sdcc_target = object.value("sdcc_target").toObject();
    ui->combobox_brand->setCurrentText(sdcc_target.value("brand").toString());
    ui->combobox_model->setCurrentText(sdcc_target.value("model").toString());
    ui->combobox_data_mode->setCurrentText(sdcc_target.value("data_mode").toString());
    ui->lineedit_crystal->setText(sdcc_target.value("crystal").toString());

    QJsonObject code = sdcc_target.value("code").toObject();
    ui->lineedit_code_start1->setText(code.value("code1_start").toString());
    ui->lineedit_code_start2->setText(code.value("code2_start").toString());
    ui->lineedit_code_start3->setText(code.value("code3_start").toString());
    ui->lineedit_code_length1->setText(code.value("code1_length").toString());
    ui->lineedit_code_length2->setText(code.value("code2_length").toString());
    ui->lineedit_code_length3->setText(code.value("code3_length").toString());
    QJsonObject xdata = sdcc_target.value("xdata").toObject();
    ui->lineedit_xdata_start1->setText(xdata.value("xdata1_start").toString());
    ui->lineedit_xdata_start2->setText(xdata.value("xdata2_start").toString());
    ui->lineedit_xdata_start3->setText(xdata.value("xdata3_start").toString());
    ui->lineedit_xdata_length1->setText(xdata.value("xdata1_length").toString());
    ui->lineedit_xdata_length2->setText(xdata.value("xdata2_length").toString());
    ui->lineedit_xdata_length3->setText(xdata.value("xdata3_length").toString());

    QJsonObject homepage = object.value("homepage").toObject();
    ui->lineedit_url->setText(homepage.value("url").toString());

    QJsonObject sdcc_output = object.value("sdcc_output").toObject();
    ui->lineedit_output_file_name->setText(sdcc_output.value("out_name").toString());
    ui->lineedit_output_folder_path->setText(sdcc_output.value("out_path").toString());
    if(sdcc_output.value("out_type").toString() == "exe")
    {
       ui->radio_create_exe->setChecked(true);
    }else
    {
       ui->radio_create_lib->setChecked(true);
    }
    ui->checkbox_output_debug_info->setChecked(sdcc_output.value("out_debug_info").toString() == "1");
    ui->combobox_output_format->setCurrentText(sdcc_output.value("out_format").toString());

    QJsonObject sdcc_list = object.value("sdcc_list").toObject();
    ui->lineedit_list_file_output_folder_path->setText(sdcc_list.value("path").toString());
    ui->checkbox_asm_list->setChecked(sdcc_list.value("asm").toString() == "1");
    ui->checkbox_asm_list_lst->setChecked(sdcc_list.value("asm_lst").toString() == "1");
    ui->checkbox_asm_list_rel->setChecked(sdcc_list.value("asm_rel").toString() == "1");
    ui->checkbox_asm_list_sym->setChecked(sdcc_list.value("asm_sym").toString() == "1");
    ui->checkbox_clan->setChecked(sdcc_list.value("clan").toString() == "1");
    ui->checkbox_link_list->setChecked(sdcc_list.value("link").toString() == "1");

    QJsonObject sdcc_user = object.value("sdcc_user").toObject();
    QJsonObject compile_before = sdcc_user.value("compile_before").toObject();
    ui->checkbox_compile_before_run1->setChecked(compile_before.value("run1").toString() == "1");
    ui->lineedit_compile_before_run1_path->setText(compile_before.value("run1_path").toString());
    ui->checkbox_compile_before_run2->setChecked(compile_before.value("run2").toString() == "1");
    ui->lineedit_compile_before_run2_path->setText(compile_before.value("run2_path").toString());
    QJsonObject build_before = sdcc_user.value("build_before").toObject();
    ui->checkbox_build_before_run1->setChecked(build_before.value("run1").toString() == "1");
    ui->lineedit_build_before_run1_path->setText(build_before.value("run1_path").toString());
    ui->checkbox_build_before_run2->setChecked(build_before.value("run2").toString() == "1");
    ui->lineedit_build_before_run2_path->setText(build_before.value("run2_path").toString());
    build_before.insert("build_before", QJsonValue(build_before));
    QJsonObject build_after = sdcc_user.value("build_after").toObject();
    ui->checkbox_build_after_run1->setChecked(build_after.value("run1").toString() == "1");
    ui->lineedit_build_after_run1_path->setText(build_after.value("run1_path").toString());
    ui->checkbox_build_after_run2->setChecked(build_after.value("run2").toString() == "1");
    ui->lineedit_build_after_run2_path->setText(build_after.value("run2_path").toString());

    QJsonObject sdcc_cparam = object.value("sdcc_cparam").toObject();
    ui->lineedit_ccpp_define->setText(sdcc_cparam.value("def").toString());
    ui->lineedit_ccpp_undefine->setText(sdcc_cparam.value("undef").toString());
    ui->combobox_standard_compliance->setCurrentText(sdcc_cparam.value("std").toString());
    ui->combobox_optimization_focus->setCurrentText(sdcc_cparam.value("optimization").toString());
    ui->lineedit_ccpp_contain_paths->setText(sdcc_cparam.value("paths").toString());
    ui->lineedit_ccpp_other_control->setText(sdcc_cparam.value("other_control").toString());
    ui->textedit_ccpp_summary->setText(sdcc_cparam.value("summary").toString());
    ui->checkbox_less_pedantic->setChecked(sdcc_cparam.value("checkbox_less_pedantic").toString() == "1");
    ui->checkbox_werror->setChecked(sdcc_cparam.value("checkbox_werror").toString() == "1");
    ui->checkbox_fsigned_char->setChecked(sdcc_cparam.value("checkbox_fsigned_char").toString() == "1");
    ui->checkbox_fdollars_in_identifiers->setChecked(sdcc_cparam.value("checkbox_fdollars_in_identifiers").toString() == "1");
    ui->checkbox_int_long_reent->setChecked(sdcc_cparam.value("checkbox_int_long_reent").toString() == "1");
    ui->checkbox_stack_auto->setChecked(sdcc_cparam.value("checkbox_stack_auto").toString() == "1");
    ui->checkbox_nostdinc->setChecked(sdcc_cparam.value("checkbox_nostdinc").toString() == "1");
    ui->checkbox_xram_movc->setChecked(sdcc_cparam.value("checkbox_xram_movc").toString() == "1");
    ui->checkbox_nooverlay->setChecked(sdcc_cparam.value("checkbox_nooverlay").toString() == "1");
    ui->checkbox_nogcse->setChecked(sdcc_cparam.value("checkbox_nogcse").toString() == "1");
    ui->checkbox_nolabelopt->setChecked(sdcc_cparam.value("checkbox_nolabelopt").toString() == "1");
    ui->checkbox_noloopreverse->setChecked(sdcc_cparam.value("checkbox_noloopreverse").toString() == "1");
    ui->checkbox_no_peep->setChecked(sdcc_cparam.value("checkbox_no_peep").toString() == "1");
    ui->checkbox_noinvariant->setChecked(sdcc_cparam.value("checkbox_noinvariant").toString() == "1");
    ui->checkbox_noinduction->setChecked(sdcc_cparam.value("checkbox_noinduction").toString() == "1");
    ui->checkbox_float_reent->setChecked(sdcc_cparam.value("checkbox_float_reent").toString() == "1");

    QJsonObject sdcc_asm = object.value("sdcc_asm").toObject();
    ui->lineedit_asm_define->setText(sdcc_asm.value("def").toString());
    ui->lineedit_asm_undefine->setText(sdcc_asm.value("undef").toString());
    ui->checkBox_j->setChecked(sdcc_asm.value("checkBox_j").toString() == "1");
    ui->checkBox_p->setChecked(sdcc_asm.value("checkBox_p").toString() == "1");
    ui->checkBox_a->setChecked(sdcc_asm.value("checkBox_a").toString() == "1");
    ui->checkBox_g->setChecked(sdcc_asm.value("checkBox_g").toString() == "1");
    ui->lineedit_asm_contain_paths->setText(sdcc_asm.value("paths").toString());
    ui->lineedit_asm_other_control->setText(sdcc_asm.value("other_control").toString());
    ui->textedit_asm_summary->setText(sdcc_asm.value("summary").toString());

    QJsonObject sdcc_linker = object.value("sdcc_linker").toObject();
    ui->checkBox_use_target_plan->setChecked(sdcc_linker.value("use_target_plan").toString() == "1");
    ui->checkbox_nostdlib->setChecked(sdcc_linker.value("nostdlib").toString() == "1");
    ui->lineedit_disable_warning_numbers->setText(sdcc_linker.value("disable_warninig_number").toString());
    ui->lineedit_xram_start->setText(sdcc_linker.value("xram_start").toString());
    ui->lineedit_xram_length->setText(sdcc_linker.value("xram_length").toString());
    ui->lineedit_iram_length->setText(sdcc_linker.value("iram_length").toString());
    ui->lineedit_xstack_start->setText(sdcc_linker.value("xstack_start").toString());
    ui->lineedit_stack_start->setText(sdcc_linker.value("stack_start").toString());
    ui->lineedit_data_start->setText(sdcc_linker.value("data_start").toString());
    ui->lineedit_code_start->setText(sdcc_linker.value("code_start").toString());
    ui->lineedit_code_length->setText(sdcc_linker.value("code_length").toString());
    ui->lineedit_data_length->setText(sdcc_linker.value("data_length").toString());
    ui->lineedit_code_name->setText(sdcc_linker.value("code_name").toString());
    ui->lineedit_const_name->setText(sdcc_linker.value("const_name").toString());
    ui->lineedit_linker_contain_paths->setText(sdcc_linker.value("lib_paths").toString());
    ui->lineedit_linker_contain_lib_files->setText(sdcc_linker.value("lib_files").toString());
    ui->lineedit_linker_other_control->setText(sdcc_linker.value("other_control").toString());
    ui->textedit_linker_summary->setText(sdcc_linker.value("summary").toString());
}

QJsonObject VProjectAttributeDialog::get_current_setting()
{
    QJsonObject parent;

    QJsonObject sdcc_target;
    sdcc_target.insert("brand", QJsonValue(ui->combobox_brand->currentText()));
    sdcc_target.insert("model", QJsonValue(ui->combobox_model->currentText()));
    sdcc_target.insert("data_mode", QJsonValue(ui->combobox_data_mode->currentText()));
    sdcc_target.insert("crystal", QJsonValue(ui->lineedit_crystal->text()));
    QJsonObject code;
    code.insert("code1_start", QJsonValue(ui->lineedit_code_start1->text()));
    code.insert("code2_start", QJsonValue(ui->lineedit_code_start2->text()));
    code.insert("code3_start", QJsonValue(ui->lineedit_code_start3->text()));
    code.insert("code1_length", QJsonValue(ui->lineedit_code_length1->text()));
    code.insert("code2_length", QJsonValue(ui->lineedit_code_length2->text()));
    code.insert("code3_length", QJsonValue(ui->lineedit_code_length3->text()));
    sdcc_target.insert("code", QJsonValue(code));
    QJsonObject xdata;
    xdata.insert("xdata1_start", QJsonValue(ui->lineedit_xdata_start1->text()));
    xdata.insert("xdata2_start", QJsonValue(ui->lineedit_xdata_start2->text()));
    xdata.insert("xdata3_start", QJsonValue(ui->lineedit_xdata_start3->text()));
    xdata.insert("xdata1_length", QJsonValue(ui->lineedit_xdata_length1->text()));
    xdata.insert("xdata2_length", QJsonValue(ui->lineedit_xdata_length2->text()));
    xdata.insert("xdata3_length", QJsonValue(ui->lineedit_xdata_length3->text()));
    sdcc_target.insert("xdata", QJsonValue(xdata));
    parent.insert("sdcc_target", QJsonValue(sdcc_target));

    QJsonObject homepage;
    homepage.insert("url", QJsonValue(ui->lineedit_url->text()));
    parent.insert("homepage", QJsonValue(homepage));

    QJsonObject sdcc_output;
    sdcc_output.insert("out_name", QJsonValue(ui->lineedit_output_file_name->text()));
    sdcc_output.insert("out_path", QJsonValue(ui->lineedit_output_folder_path->text()));
    if(ui->radio_create_exe->isChecked())
    {
        sdcc_output.insert("out_type", QJsonValue("exe"));
    }else
    {
        sdcc_output.insert("out_type", QJsonValue("lib"));
    }
    sdcc_output.insert("out_debug_info", QJsonValue(QString::number(ui->checkbox_output_debug_info->isChecked()?1:0)));
    sdcc_output.insert("out_format", QJsonValue(ui->combobox_output_format->currentText()));
    parent.insert("sdcc_output", QJsonValue(sdcc_output));

    QJsonObject sdcc_list;
    sdcc_list.insert("path", QJsonValue(ui->lineedit_list_file_output_folder_path->text()));
    sdcc_list.insert("asm", QJsonValue(QString::number(ui->checkbox_asm_list->isChecked()?1:0)));
    sdcc_list.insert("asm_lst", QJsonValue(QString::number(ui->checkbox_asm_list_lst->isChecked()?1:0)));
    sdcc_list.insert("asm_rel", QJsonValue(QString::number(ui->checkbox_asm_list_rel->isChecked()?1:0)));
    sdcc_list.insert("asm_sym", QJsonValue(QString::number(ui->checkbox_asm_list_sym->isChecked()?1:0)));
    sdcc_list.insert("clan", QJsonValue(QString::number(ui->checkbox_clan->isChecked()?1:0)));
    sdcc_list.insert("link", QJsonValue(QString::number(ui->checkbox_link_list->isChecked()?1:0)));
    parent.insert("sdcc_list", QJsonValue(sdcc_list));

    QJsonObject sdcc_user;
    QJsonObject compile_before;
    compile_before.insert("run1", QJsonValue(QString::number(ui->checkbox_compile_before_run1->isChecked()?1:0)));
    compile_before.insert("run1_path", QJsonValue(ui->lineedit_compile_before_run1_path->text()));
    compile_before.insert("run2", QJsonValue(QString::number(ui->checkbox_compile_before_run2->isChecked()?1:0)));
    compile_before.insert("run2_path", QJsonValue(ui->lineedit_compile_before_run2_path->text()));
    sdcc_user.insert("compile_before", QJsonValue(compile_before));
    QJsonObject build_before;
    build_before.insert("run1", QJsonValue(QString::number(ui->checkbox_build_before_run1->isChecked()?1:0)));
    build_before.insert("run1_path", QJsonValue(ui->lineedit_build_before_run1_path->text()));
    build_before.insert("run2", QJsonValue(QString::number(ui->checkbox_build_before_run2->isChecked()?1:0)));
    build_before.insert("run2_path", QJsonValue(ui->lineedit_build_before_run2_path->text()));
    sdcc_user.insert("build_before", QJsonValue(build_before));
    QJsonObject build_after;
    build_after.insert("run1", QJsonValue(QString::number(ui->checkbox_build_after_run1->isChecked()?1:0)));
    build_after.insert("run1_path", QJsonValue(ui->lineedit_build_after_run1_path->text()));
    build_after.insert("run2", QJsonValue(QString::number(ui->checkbox_build_after_run2->isChecked()?1:0)));
    build_after.insert("run2_path", QJsonValue(ui->lineedit_build_after_run2_path->text()));
    sdcc_user.insert("build_after", QJsonValue(build_after));
    parent.insert("sdcc_user", QJsonValue(sdcc_user));

    QJsonObject cparam;
    cparam.insert("def", QJsonValue(ui->lineedit_ccpp_define->text()));
    cparam.insert("undef", QJsonValue(ui->lineedit_ccpp_undefine->text()));
    cparam.insert("std", QJsonValue(ui->combobox_standard_compliance->currentText()));
    cparam.insert("optimization", QJsonValue(ui->combobox_optimization_focus->currentText()));
    cparam.insert("paths", QJsonValue(ui->lineedit_ccpp_contain_paths->text()));
    cparam.insert("other_control", QJsonValue(ui->lineedit_ccpp_other_control->text()));
    cparam.insert("summary", QJsonValue(ui->textedit_ccpp_summary->toPlainText()));
    cparam.insert("checkbox_less_pedantic", QJsonValue(QString::number(ui->checkbox_less_pedantic->isChecked()?1:0)));
    cparam.insert("checkbox_werror", QJsonValue(QString::number(ui->checkbox_werror->isChecked()?1:0)));
    cparam.insert("checkbox_fsigned_char", QJsonValue(QString::number(ui->checkbox_fsigned_char->isChecked()?1:0)));
    cparam.insert("checkbox_fdollars_in_identifiers", QJsonValue(QString::number(ui->checkbox_fdollars_in_identifiers->isChecked()?1:0)));
    cparam.insert("checkbox_int_long_reent", QJsonValue(QString::number(ui->checkbox_int_long_reent->isChecked()?1:0)));
    cparam.insert("checkbox_stack_auto", QJsonValue(QString::number(ui->checkbox_stack_auto->isChecked()?1:0)));
    cparam.insert("checkbox_nostdinc", QJsonValue(QString::number(ui->checkbox_nostdinc->isChecked()?1:0)));
    cparam.insert("checkbox_xram_movc", QJsonValue(QString::number(ui->checkbox_xram_movc->isChecked()?1:0)));
    cparam.insert("checkbox_nooverlay", QJsonValue(QString::number(ui->checkbox_nooverlay->isChecked()?1:0)));
    cparam.insert("checkbox_nogcse", QJsonValue(QString::number(ui->checkbox_nogcse->isChecked()?1:0)));
    cparam.insert("checkbox_nolabelopt", QJsonValue(QString::number(ui->checkbox_nolabelopt->isChecked()?1:0)));
    cparam.insert("checkbox_noloopreverse", QJsonValue(QString::number(ui->checkbox_noloopreverse->isChecked()?1:0)));
    cparam.insert("checkbox_no_peep", QJsonValue(QString::number(ui->checkbox_no_peep->isChecked()?1:0)));
    cparam.insert("checkbox_noinvariant", QJsonValue(QString::number(ui->checkbox_noinvariant->isChecked()?1:0)));
    cparam.insert("checkbox_noinduction", QJsonValue(QString::number(ui->checkbox_noinduction->isChecked()?1:0)));
    cparam.insert("checkbox_float_reent", QJsonValue(QString::number(ui->checkbox_float_reent->isChecked()?1:0)));
    parent.insert("sdcc_cparam", QJsonValue(cparam));

    QJsonObject sdcc_asm;
    sdcc_asm.insert("def", QJsonValue(ui->lineedit_asm_define->text()));
    sdcc_asm.insert("undef", QJsonValue(ui->lineedit_asm_undefine->text()));
    sdcc_asm.insert("checkBox_j", QJsonValue(QString::number(ui->checkBox_j->isChecked()?1:0)));
    sdcc_asm.insert("checkBox_p", QJsonValue(QString::number(ui->checkBox_p->isChecked()?1:0)));
    sdcc_asm.insert("checkBox_a", QJsonValue(QString::number(ui->checkBox_a->isChecked()?1:0)));
    sdcc_asm.insert("checkBox_g", QJsonValue(QString::number(ui->checkBox_g->isChecked()?1:0)));
    sdcc_asm.insert("paths", QJsonValue(ui->lineedit_asm_contain_paths->text()));
    sdcc_asm.insert("other_control", QJsonValue(ui->lineedit_asm_other_control->text()));
    sdcc_asm.insert("summary", QJsonValue(ui->textedit_asm_summary->toPlainText()));
    parent.insert("sdcc_asm", QJsonValue(sdcc_asm));

    QJsonObject sdcc_linker;
    sdcc_linker.insert("use_target_plan", QJsonValue(QString::number(ui->checkBox_use_target_plan->isChecked()?1:0)));
    sdcc_linker.insert("nostdlib", QJsonValue(QString::number(ui->checkbox_nostdlib->isChecked()?1:0)));
    sdcc_linker.insert("disable_warninig_number", QJsonValue(ui->lineedit_disable_warning_numbers->text()));
    sdcc_linker.insert("xram_start", QJsonValue(ui->lineedit_xram_start->text()));
    sdcc_linker.insert("xram_length", QJsonValue(ui->lineedit_xram_length->text()));
    sdcc_linker.insert("iram_length", QJsonValue(ui->lineedit_iram_length->text()));
    sdcc_linker.insert("xstack_start", QJsonValue(ui->lineedit_xstack_start->text()));
    sdcc_linker.insert("stack_start", QJsonValue(ui->lineedit_stack_start->text()));
    sdcc_linker.insert("data_start", QJsonValue(ui->lineedit_data_start->text()));
    sdcc_linker.insert("code_start", QJsonValue(ui->lineedit_code_start->text()));
    sdcc_linker.insert("code_length", QJsonValue(ui->lineedit_code_length->text()));
    sdcc_linker.insert("data_length", QJsonValue(ui->lineedit_data_length->text()));
    sdcc_linker.insert("code_name", QJsonValue(ui->lineedit_code_name->text()));
    sdcc_linker.insert("const_name", QJsonValue(ui->lineedit_const_name->text()));
    sdcc_linker.insert("lib_paths", QJsonValue(ui->lineedit_linker_contain_paths->text()));
    sdcc_linker.insert("lib_files", QJsonValue(ui->lineedit_linker_contain_lib_files->text()));
    sdcc_linker.insert("other_control", QJsonValue(ui->lineedit_linker_other_control->text()));
    sdcc_linker.insert("summary", QJsonValue(ui->textedit_linker_summary->toPlainText()));
    parent.insert("sdcc_linker", QJsonValue(sdcc_linker));

    return parent;
}

void VProjectAttributeDialog::save_setting()
{
    _project_json.insert("attribute", QJsonValue(get_current_setting()));
    VFunctions::save_file(_project_path, QJsonDocument(_project_json).toJson());
}

VProjectAttributeDialog::~VProjectAttributeDialog()
{
    delete ui;
}

void VProjectAttributeDialog::full_path(QLineEdit *lineedit, int type, QString filter)
{
    QString path;
    if(type == TYPE::FILE)
    {
        path = QFileDialog::getOpenFileName(this, "选择文件", lineedit->text(), filter);
    }
    else if(type == TYPE::FOLDER)
    {
        path = QFileDialog::getExistingDirectory(this, "选择路径", lineedit->text());
    }
    if(path.isEmpty() == false)
    {
        lineedit->setText(path);
    }
}

void VProjectAttributeDialog::full_paths(QLineEdit *lineedit, int type, QString filter)
{
    VPathEditDialog dlg(this, _project_path, lineedit->text().split(";"));
    if(type == TYPE::FILE)
    {
        dlg._type = TYPE::FILE;
        dlg._filter = filter;
    }
    else if(type == TYPE::FOLDER)
    {
        dlg._type = TYPE::FOLDER;
    }
    int result = dlg.exec();
    if(result == QDialog::Accepted)
    {
        lineedit->setText(dlg._list.join(';'));
    }
}

void VProjectAttributeDialog::on_update_configure()
{
    QStringList ccpp_list;

    ccpp_list.append("-mmcs51");

    switch (ui->combobox_data_mode->currentIndex()) {
    case 0:
        ccpp_list.append("--model-small");
        break;
    case 1:
        ccpp_list.append("--model-medium");
        break;
    case 2:
        ccpp_list.append("--model-large");
        break;
    }

    if(ui->checkbox_output_debug_info->isChecked())
    {
        ccpp_list.append("--debug");
    }

    switch (ui->combobox_standard_compliance->currentIndex()) {
    case 0:
        ccpp_list.append("--std-c89");
        break;
    case 1:
        ccpp_list.append("--std-sdcc89");
        break;
    case 2:
        ccpp_list.append("--std-c99");
        break;
    case 3:
        ccpp_list.append("--std-sdcc99");
        break;
    }

    // define
    foreach(QString s, get_param_list(ui->lineedit_ccpp_define->text(), ' '))
    {
        if(s.isEmpty() == false)
        {
            ccpp_list.append("-D" + s);
        }

    }

    if(ui->checkbox_less_pedantic->isChecked())
    {
        ccpp_list.append("--less-pedantic");
    }
    if (ui->checkbox_werror->isChecked())
    {
        ccpp_list.append("--Werror");
    }
    if (ui->checkbox_float_reent->isChecked())
    {
        ccpp_list.append("--float-reent");
    }
    if (ui->checkbox_fsigned_char->isChecked())
    {
        ccpp_list.append("--fsigned-char");
    }
    if (ui->checkbox_fdollars_in_identifiers->isChecked())
    {
        ccpp_list.append("--fdollars-in-identifiers");
    }
    if (ui->checkbox_int_long_reent->isChecked())
    {
        ccpp_list.append("--int-long-reent");
    }
    if (ui->checkbox_stack_auto->isChecked())
    {
        ccpp_list.append("--stack-auto");
    }
    if (ui->checkbox_nostdinc->isChecked())
    {
        ccpp_list.append("--nostdinc");
    }
    if (ui->checkbox_xram_movc->isChecked())
    {
        ccpp_list.append("--xram-movc");
    }

    if(ui->combobox_optimization_focus->currentIndex() != 3)
    {
        ui->checkbox_nooverlay->setEnabled(true);
        ui->checkbox_noinduction->setEnabled(true);
        ui->checkbox_nogcse->setEnabled(true);
        ui->checkbox_nolabelopt->setEnabled(true);
        ui->checkbox_noloopreverse->setEnabled(true);
        ui->checkbox_no_peep->setEnabled(true);
        ui->checkbox_noinvariant->setEnabled(true);

        if (ui->checkbox_nooverlay->isChecked())
        {
            ccpp_list.append("--nooverlay");
        }
        if (ui->checkbox_nogcse->isChecked())
        {
            ccpp_list.append("--nogcse");
        }
        if (ui->checkbox_nolabelopt->isChecked())
        {
            ccpp_list.append("--nolabelopt");
        }
        if (ui->checkbox_noloopreverse->isChecked())
        {
            ccpp_list.append("--noloopreverse");
        }
        if (ui->checkbox_no_peep->isChecked())
        {
            ccpp_list.append("--no-peep");
        }
        if (ui->checkbox_noinvariant->isChecked())
        {
            ccpp_list.append("--noinvariant");
        }
        if (ui->checkbox_noinduction->isChecked())
        {
            ccpp_list.append("--noinduction");
        }

        switch (ui->combobox_optimization_focus->currentIndex()) {
        case 0:
            ccpp_list.append("--opt-code-size");
            break;
        case 1:
            ccpp_list.append("--opt-code-speed");
            break;
        }
    }
    else
    {
        ccpp_list.append("--nooverlay");
        ccpp_list.append("--nogcse");
        ccpp_list.append("--nolabelopt");
        ccpp_list.append("--noloopreverse");
        ccpp_list.append("--no-peep");
        ccpp_list.append("--noinvariant");
        ccpp_list.append("--noinduction");

        ui->checkbox_nooverlay->setEnabled(false);
        ui->checkbox_noinduction->setEnabled(false);
        ui->checkbox_nogcse->setEnabled(false);
        ui->checkbox_nolabelopt->setEnabled(false);
        ui->checkbox_noloopreverse->setEnabled(false);
        ui->checkbox_no_peep->setEnabled(false);
        ui->checkbox_noinvariant->setEnabled(false);
    }

    foreach(QString s, get_param_list(ui->lineedit_ccpp_contain_paths->text(), ';'))
    {
        if(s.isEmpty() == false)
        {
            ccpp_list.append("-I");
            ccpp_list.append(s);
        }
    }

    foreach(QString s, get_param_list(ui->lineedit_ccpp_other_control->text(), ' '))
    {
        if(s.isEmpty() == false)
        {
            ccpp_list.append(s);
        }
    }

    ui->textedit_ccpp_summary->setText(ccpp_list.join(';'));

    QStringList asm_list;
    // define
    foreach(QString s, get_param_list(ui->lineedit_asm_define->text(), ' '))
    {
        if(s.isEmpty() == false)
        {
            asm_list.append("-D" + s);
        }

    }

    if (ui->checkBox_a->isChecked())
    {
        asm_list.append("-a");
    }
    if (ui->checkBox_g->isChecked())
    {
        asm_list.append("-g");
    }
    if (ui->checkBox_j->isChecked())
    {
        asm_list.append("-j");
    }
    if (ui->checkBox_p->isChecked())
    {
        asm_list.append("-p");
    }

    asm_list.append("-x");
    asm_list.append("-l");
    asm_list.append("-o");
    asm_list.append("-c");
    asm_list.append("-s");

    foreach(QString s, get_param_list(ui->lineedit_asm_contain_paths->text(), ';'))
    {
        if(s.isEmpty() == false)
        {
            asm_list.append("-I");
            asm_list.append(s);
        }
    }


    foreach(QString s, get_param_list(ui->lineedit_asm_other_control->text(), ' '))
    {
        if(s.isEmpty() == false)
        {
            asm_list.append(s);
        }
    }
    ui->textedit_asm_summary->setText(asm_list.join(';'));

    QStringList linker_list;

    switch (ui->combobox_data_mode->currentIndex()) {
    case 0:
        linker_list.append("--model-small");
        break;
    case 1:
        linker_list.append("--model-medium");
        break;
    case 2:
        linker_list.append("--model-large");
        break;
    }

    if(ui->checkbox_nostdlib->isChecked())
    {
        linker_list.append("--nostdlib");
    }

    foreach(QString s, get_param_list(ui->lineedit_disable_warning_numbers->text(), ' '))
    {
        if(s.trimmed().isEmpty() == false)
        {
            linker_list.append("--disable-warnin");
            linker_list.append(s.trimmed());
        }

    }

    QString text;
    if(ui->checkBox_use_target_plan->isChecked())
    {
        text = ui->lineedit_code_start1->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--code-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_code_length1->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--code-size");
            linker_list.append(text);
        }
        text = ui->lineedit_xdata_start1->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--xram-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_xdata_length1->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--xram-size");
            linker_list.append(text);
        }
    }
    else
    {
        text = ui->lineedit_iram_length->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--iram-size");
            linker_list.append(text);
        }
        text = ui->lineedit_stack_start->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--stack-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_xram_start->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--xram-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_xram_length->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--xram-size");
            linker_list.append(text);
        }
        text = ui->lineedit_data_start->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--data-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_data_length->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--data-size");
            linker_list.append(text);
        }
        text = ui->lineedit_code_start->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--code-loc");
            linker_list.append(text);
        }
        text = ui->lineedit_code_length->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--code-size");
            linker_list.append(text);
        }
        text = ui->lineedit_code_name->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--codeseg");
            linker_list.append(text);
        }
        text = ui->lineedit_const_name->text().trimmed();
        if(text.isEmpty() == false)
        {
            linker_list.append("--constseg");
            linker_list.append(text);
        }
    }

    foreach(QString s, get_param_list(ui->lineedit_linker_contain_lib_files->text(), ';'))
    {
        if(s.isEmpty() == false)
        {
            linker_list.append(s);
        }
    }

    foreach(QString s, get_param_list(ui->lineedit_linker_contain_paths->text(), ';'))
    {
        if(s.isEmpty() == false)
        {
            linker_list.append(s);
        }
    }

    foreach(QString s, get_param_list(ui->lineedit_linker_other_control->text(), ' '))
    {
        if(s.isEmpty() == false)
        {
            linker_list.append(s);
        }
    }

    if(ui->checkbox_output_debug_info->isChecked())
    {
        linker_list.append("--debug");
    }

    if(ui->radio_create_exe->isChecked())
    {
        linker_list.append("--out-fmt-ihx");
    }

    ui->textedit_linker_summary->setText(linker_list.join(';'));

    ui->btn_apply->setEnabled(true);
}

QStringList VProjectAttributeDialog::get_param_list(QString text, QChar sep)
{
    text = text.replace(QRegExp("\\s+"), sep);
    return text.split(" ");
}

void VProjectAttributeDialog::on_btn_user_select_compile_run1_path_clicked()
{
    full_path(ui->lineedit_compile_before_run1_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_user_select_compile_run2_path_clicked()
{
    full_path(ui->lineedit_compile_before_run2_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_user_select_build_before_run1_path_clicked()
{
    full_path(ui->lineedit_build_before_run1_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_user_select_build_before_run2_path_clicked()
{
    full_path(ui->lineedit_build_before_run2_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_user_select_build_after_run1_path_clicked()
{
    full_path(ui->lineedit_build_after_run1_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_user_select_build_after_run2_path_clicked()
{
    full_path(ui->lineedit_build_after_run2_path, TYPE::FILE, "Files(*.exe ; *.bat)");
}

void VProjectAttributeDialog::on_btn_output_select_folder_clicked()
{
    full_path(ui->lineedit_output_folder_path, TYPE::FOLDER);
}

void VProjectAttributeDialog::on_btn_ccpp_select_contain_path_clicked()
{
    full_paths(ui->lineedit_ccpp_contain_paths, TYPE::FOLDER);
}

void VProjectAttributeDialog::on_btn_linker_select_contain_lib_files_clicked()
{
    full_paths(ui->lineedit_linker_contain_lib_files, TYPE::FILE, "lib(*.lib)");
}

void VProjectAttributeDialog::on_btn_linker_select_contain_lib_paths_clicked()
{
    full_paths(ui->lineedit_linker_contain_paths, TYPE::FOLDER);
}

void VProjectAttributeDialog::on_btn_asm_select_contain_paths_clicked()
{
    full_paths(ui->lineedit_asm_contain_paths, TYPE::FOLDER);
}

void VProjectAttributeDialog::on_btn_apply_clicked()
{
    ui->btn_apply->setEnabled(false);
    save_setting();
    _changed = true;
}

void VProjectAttributeDialog::on_btn_ok_clicked()
{
    save_setting();
    _changed = true;
    this->accept();
}

void VProjectAttributeDialog::on_btn_cancel_clicked()
{
    this->reject();
}

void VProjectAttributeDialog::on_btn_list_select_output_folder_clicked()
{
    full_path(ui->lineedit_list_file_output_folder_path, TYPE::FOLDER);
}

void VProjectAttributeDialog::on_combobox_brand_currentIndexChanged(const QString &arg1)
{

}

void VProjectAttributeDialog::on_combobox_brand_currentIndexChanged(int index)
{
    QStringList list = ui->combobox_brand->itemData(index).value<QStringList>();

    ui->combobox_model->clear();
    foreach(QString path, list)
    {
        ui->combobox_model->addItem(QFileInfo(path).fileName());
    }
}
